package com.tpl.core.basedata.service.sys.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.tpl.core.basedata.dao.FileDao;
import com.tpl.core.common.exception.RuleException;
import com.tpl.core.dao.ExecuteSql;
import com.tpl.core.entity.sys.Files;
import com.alibaba.fastjson.JSONObject;
import com.tpl.core.basedata.service.sys.FileService;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;

public class FileServiceImpl  implements FileService {
	
	@Autowired
	private FileDao fileDao;
	
	@Override
	public List<Files> getDirList(String userNo, String fileType, Long deptId) {
		List<Files> list = fileDao.getSelfDirList(userNo, fileType,deptId);
		boolean hasOwner=false;
		if(StringUtils.isNotBlank(userNo)){
			for(Files f:list){
//				if("private".equals(f.getFileName())){ //显示去掉私有文件夹节点
//				}
				if(f.getPubFlag()==0){
					if(f.getFileName().equals(userNo)){
						f.setParentId(-1L);
						f.setSourceName("我的文件夹");
						hasOwner=true;
					}
				}
			}
			//int count = fileDao.getFileCount(userNo);
			//用户还没用自己的文件夹，在list中新增一个
			if(!hasOwner){
				Files f = new Files();
				f.setId(null);
				f.setFileName("我的文件夹");
				f.setSourceName("我的文件夹");
				f.setPubFlag(0);
				f.setParentId(-1L);
				list.add(f);
			}
		}
		//增加一个回收站
		Files f = new Files();
		f.setId(0L);
		f.setSourceName("回收站");
		f.setParentId(-1L);
		f.setPubFlag(3);
		list.add(f);
		
		return list;
	}

	@Override
	public List<Files> getFileById(Long pid, Long deptId) {
		List<Files> list = fileDao.getSelfFileList(pid, deptId);
		return list;
	}

	@Override
	public String getDirPath(Long pid) {
		String path = ExecuteSql.getSingleResult("select Concat(f.PATH,f.FILE_NAME,'/') from bd_file f where f.id=?", pid);
		return path;
	}

	@Override
	public Files getFilesByMd5(String md5) {
		Files file = fileDao.getFilesByMd5(md5);
		return file;
	}

	@Override
	public void saveFile(Files file) {
		fileDao.insertFile(file);
	}

	@Override
	public Boolean isRepeat(Long pid, String sourceName, String md5) {
		String count = ExecuteSql.getSingleResult("select count(1) from bd_file f where f.SOURCE_NAME=? and MD5=? and f.PARENT_ID=? and f.state=1",sourceName,md5,pid);
		if("0".equals(count)){
			return false;
		}
		return true;
	}

	@Override
	public void saveDir(Files f) {
		fileDao.insertFile(f);
	}

	@Override
	public void updateName(Long id, Long pid, String sourceName) {
		String sql="select count(1) from bd_file f where f.PARENT_ID=? and f.SOURCE_NAME=? and f.ID!=?";
		String count = ExecuteSql.getSingleResult(sql,pid,sourceName,id);
		//存在重名文件
		if(!"0".equals(count)){
			throw new RuleException("此目录已包含名为\""+sourceName+"\"的文件(夹)。");
		}
		ExecuteSql.execute("update bd_file f set f.SOURCE_NAME=? where f.ID=?", sourceName,id);
	}


	@Override
	public void delDirById(Long id) {
		String sql ="update bd_file f set f.state=2 where f.ID=? and not EXISTS(select 1 from (select 1 from bd_file bf where bf.parent_id=? and bf.state=1)t)";
		int update = ExecuteSql.execute(sql, id, id);
		if(update<1)
			throw new RuleException("存在子文件!");
	}
	
	

	@Override
	public String getNewDirName(Long pid) {
		String sql="SELECT SUBSTR(f.source_name,6) from bd_file f where f.SOURCE_NAME like '新建文件夹%' and f.PARENT_ID=? and f.STATE=1";
		List<Object[]> list=ExecuteSql.getFields(sql, pid);
		Map map=new HashMap();
		for(Object[] obs : list)
			map.put(obs[0], 1);
		int i=1;
		while(true){
			Object rel=map.get("("+i+")");
			if(rel==null)break;
			i++;
		}
		return i==1?"新建文件夹":"新建文件夹("+i+")";
	}

	@Override
	public void updateState(String ids,String state) {
		String sql ="update bd_file f set f.state=? where f.ID in ("+ids+")";
		ExecuteSql.execute(sql,state);
	}



	@Override
	public String updateFiles(Long pid, String ids,String type,String publicFlag) {
		List<Files> list = fileDao.getRepeat(pid, ids); //取出重复的文件
		Map<String, String> map = new HashMap<String, String>();
		String createDate = DateTime.now().toString("yyyy-MM-dd HH:mm:ss");
		String userNo = "";//SessionUtils.getLoginUserNo();
		String result = null;
		Map<String, String> oldIds = new HashMap<String, String>();//被删除过的文件
		if(list.size()>0){ //存在重复
			String names ="";
			for(Files f:list){
				String[] repeatIds = f.getRepeatIds().split(",");
				if(repeatIds[0].endsWith("_"))
					(f.getState()>1?oldIds:map).put(repeatIds[0].replace("_", ""), repeatIds[1]);
				else
					(f.getState()>1?oldIds:map).put(repeatIds[1].replace("_", ""), repeatIds[0]);
				if(f.getState()==1)
					names += "、"+f.getSourceName();
			}
			JSONObject json = new JSONObject();
			JSONObject json2 = new JSONObject().fluentPutAll(map);
			if(StringUtils.isNotEmpty(names)){
				json.put("names", names.substring(1));
				json.put("map", json2);
				result = json.toString();
			}
		}
		String[] id = ids.split(",");
		String sql = "insert into bd_file(FILE_NAME,PATH,SOURCE_NAME,CREATE_DATE,CREATOR,PARENT_ID,FILE_TYPE,PUB_FLAG,FILE_SUFFIX,FILE_SIZE,STATE,MD5,UPDATE_DATE,IS_COPY)\n" +
				"select FILE_NAME,PATH,SOURCE_NAME,?,?,?,FILE_TYPE,?,FILE_SUFFIX,FILE_SIZE,STATE,MD5,?,? from bd_file \n" +
				"where id=?";//插入新文件
		String sql2 = "update bd_file f set f.UPDATE_DATE=?,f.UPDATOR=?,f.STATE=2 where id =?";//修改原文件状态
		List<Serializable[]> params = new ArrayList<Serializable[]>();
		List<Serializable[]> params2 = new ArrayList<Serializable[]>();
		for(String i:id){
			if(map==null ||map.get(i)==null){
				params.add(new Serializable[]{createDate,userNo,pid,publicFlag,createDate,i,i});
				if("cut".equals(type))
					params2.add(new Serializable[]{createDate,userNo,i});
			}
		}
		if(!oldIds.isEmpty()){//替换已经删除的文件
			List<Files> oldList = fileDao.getFileByIds(Arrays.toString(oldIds.keySet().toArray(new String[0])).replaceAll("\\[|\\]", ""));
			List<Serializable[]> oldParams = new ArrayList<Serializable[]>();
			String sql3 ="UPDATE bd_file f\n" +
					"SET PATH =?, FILE_NAME =?, FILE_SIZE =?, MD5 =?, UPDATE_DATE =?, UPDATOR =?, IS_COPY =?,PUB_FLAG=?\n" +
					"WHERE	id =?";
			for(Files f : oldList){
				oldParams.add(new Serializable[]{f.getPath(),f.getFileName(),f.getFileSize(),f.getMd5(),createDate,userNo,
						1,publicFlag,(Serializable) oldIds.get(String.valueOf(f.getId()))});
			}
			ExecuteSql.executeBatch(sql3, oldParams.toArray(new Serializable[0][]));
		}
		if("cut".equals(type))//如果为剪切，改为删除状态
			ExecuteSql.executeBatch(sql2, params.toArray(new Serializable[0][]));
		ExecuteSql.executeBatch(sql, params.toArray(new Serializable[0][]));
		return result;
	}

	@Override
	public void updateFiles(String ids,String type,String publicFlag) {
		JSONObject j = JSONObject.parseObject(ids);
		
		List<Serializable[]> params = new ArrayList<Serializable[]>();
		String createDate = DateTime.now().toString("yyyy-MM-dd HH:mm:ss");
		String userNo = "";//SessionUtils.getLoginUserNo();
		String oldIds="0";
		for(Object k:j.keySet())
			oldIds+=","+String.valueOf(k);
		List<Files> list = fileDao.getFileByIds(oldIds);
		if("cut".equals(type)){//如果为剪切，改为删除状态
			String sql = "update bd_file f set f.UPDATE_DATE=?,f.UPDATOR=?,f.STATE=2 where id in ("+oldIds+")";
			ExecuteSql.execute(sql, createDate,userNo);
		}
		String sql ="UPDATE bd_file f\n" +
				"SET PATH =?, FILE_NAME =?, FILE_SIZE =?, MD5 =?, UPDATE_DATE =?, UPDATOR =?, IS_COPY =?,PUB_FLAG=?\n" +
				"WHERE	id =?";
		for(Files f : list){
			params.add(new Serializable[]{f.getPath(),f.getFileName(),f.getFileSize(),f.getMd5(),createDate,userNo,
					1,publicFlag,(Serializable) j.get(String.valueOf(f.getId()))});
		}
		ExecuteSql.executeBatch(sql, params.toArray(new Serializable[0][]));
	}

	@Override
	public List<Files> getRecycleBinFileById(Boolean pubFlag, Long deptId) {
		return  fileDao.getRecycleBinFileById(/*SessionUtils.getLoginUserNo()*/"",pubFlag, deptId);
	}

	@Override
	public Files saveDir(Long pid,boolean pubFlag) {
		String path = this.getDirPath(pid);
		if(pid==null){ //当没有当前登录人的文件夹时，新建
			Files f = this.saveUserDir();
			pid=f.getId();
			path=f.getPath()+f.getFileName()+"/";
		}
		Files f = new Files();
		f.setCreateDate(DateTime.now().toDate());
//		f.setCreator(SessionUtils.getLoginUserNo());
		f.setUpdator(f.getCreator());
		f.setUpdateDate(DateTime.now().toDate());
		f.setFileName(DateTime.now().toString("yyyyMMddHHmmssSSS"));
		f.setSourceName(this.getNewDirName(pid));
		f.setPath(path);
		f.setFileType(2);
		f.setPubFlag(pubFlag?1:0);
		f.setParentId(pid);
		f.setState(1);
		f.setDeptId(0L);
		fileDao.insertFile(f);
		return f;
	}
	
	public Files saveUserDir(){
		String pat = this.getDirPath(2L);
		Files f = new Files();
		f.setCreateDate(DateTime.now().toDate());
//		f.setCreator(SessionUtils.getLoginUserNo());
		f.setUpdator(f.getCreator());
		f.setUpdateDate(DateTime.now().toDate());
//		f.setSourceName(SessionUtils.getLoginUserNo());
		f.setFileName(f.getSourceName());
		f.setPath(pat);
		f.setFileType(2);
		f.setPubFlag(0);
		f.setParentId(2L);
		f.setState(1);
//		f.setDeptId(SessionUtils.getLoginDeptId());
		fileDao.insertFile(f);
		return f;
	}


	@Override
	public Files getFilesById(Long id) {
		return fileDao.getFilesById(id);
	}

	@Override
	public void executeTask(String sourceId) throws Exception {
		
	}
}
